package services;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import repositories.GalleryRepository;
import domain.Administrator;
import domain.Customer;
import domain.Gallery;
import domain.Painting;

@Service
@Transactional
public class GalleryService {

	// Managed Repository
	@Autowired
	private GalleryRepository galleryRepository;

	// Supporting Services
	@Autowired
	private CustomerService customerService;
	@Autowired
	private AdministratorService administratorService;

	// Constructor Method
	public GalleryService() {
		super();
	}

	// Simple Crud Methods

	public Gallery create() {
		Gallery result;
		Collection<Painting> paintings;

		paintings = new HashSet<Painting>();
		result = new Gallery();
		result.setCustomer(customerService.findByPrincipal());
		result.setPaintings(paintings);

		return result;
	}

	public void save(Gallery g) {
		Assert.notNull(g);
		Assert.isTrue(g.getCustomer().equals(customerService.findByPrincipal()));

		galleryRepository.save(g);
	}

	public void delete(Gallery g) {
		Assert.notNull(g);
		Assert.isTrue(galleryRepository.exists(g.getId()));
		Assert.isTrue(g.getPaintings().isEmpty());
		Assert.isTrue(g.getCustomer().equals(customerService.findByPrincipal()));

		galleryRepository.delete(g);
	}

	public Gallery findOne(int galleryId) {
		Gallery result;

		result = galleryRepository.findOne(galleryId);

		return result;
	}

	public Collection<Gallery> findAll() {
		Collection<Gallery> result;

		result = galleryRepository.findAll();

		return result;
	}

	// Other Business Methods

	public Collection<Gallery> findByCustomer(Customer c) {
		Collection<Gallery> result;

		result = galleryRepository.findByCustomer(c.getId());

		return result;
	}

	public Collection<Gallery> findByMoreExpensive() {
		
		Administrator principal;
		principal = administratorService.findByPrincipal();
		Assert.isTrue(principal instanceof Administrator);
		
		Collection<Object[]> objects;
		Gallery gallery;
		List<Gallery> res;
		Double totalAppraisalMax = 0.0;
		List<Integer> idres;

		res = new LinkedList<Gallery>();
		idres = new LinkedList<Integer>();
		objects = galleryRepository.findByTotalAppraisal();

		for (Object[] o : objects) {
			if(o[0] == null){
				continue;
			}else{
			int idGallery = (int) o[0];
			Double totalAppraisal = (Double) o[1];

			if (totalAppraisalMax < totalAppraisal) {
				totalAppraisalMax = totalAppraisal;
				idres.clear();
				idres.add(idGallery);
			} else if (totalAppraisalMax == totalAppraisal) {
				idres.add(idGallery);
			}
		}
		}
		for (Integer l : idres) {
			gallery = galleryRepository.findOne(l);
			res.add(gallery);

		}

		return res;

	}
}
